package com.atguigu.gmall.search.config;

import com.atguigu.gmall.common.consts.GmallConsts;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MqConsumerConfig {
    /**
     * 创建延迟队列 + 创建延迟交换机 + 绑定
     * 延迟队列用来储存业务队列里面的异常消息
     */
    //创建延迟交换机
    @Bean
    public TopicExchange delayExchange() {
        return ExchangeBuilder.topicExchange("test2_delay_exchange")
                .durable(true).ignoreDeclarationExceptions().build();
    }

    //创建延迟队列
    @Bean
    public Queue delayQueue() {
        return QueueBuilder.durable("test2_delay_queue").build();
    }

    //将上面的延迟队列和延迟交换机用路由key绑定起来
    @Bean
    public Binding delayBinding(TopicExchange delayExchange, Queue delayQueue){
        return BindingBuilder
                .bind(delayQueue)
                .to(delayExchange)
                .with("test2.delay");
    }

    /**
     * 创建死信队列 + 创建死信交换机 + 绑定
     * 死信队列用来储存业务队列里面的异常消息
     */
    //创建死信交换机
    @Bean
    public TopicExchange deadExchange() {
        return ExchangeBuilder.topicExchange("spu_dead_exchange")  //交换机类型
                .durable(true)                         //持久化
                .ignoreDeclarationExceptions()         //忽略重复声明异常
                .build();
    }

    //创建死信队列
    @Bean
    public Queue deadQueue() {
        return QueueBuilder.durable("spu_dead_queue")
//                .ttl(20000)  //配置死信队列中的过期时间，20秒，开发过程中的过期时间会长一点
//                .deadLetterExchange("test2_delay_exchange")//这里也可以配置延迟交换机
//                .deadLetterRoutingKey("test2.delay") //这里可以配置延迟队和延迟交换机的routingKey绑定
                .build();
    }

    //将上面的死信队列和死信交换机用路由key绑定起来
    @Bean
    public Binding deadBind(TopicExchange deadExchange, Queue deadQueue) {
        return BindingBuilder.bind(deadQueue)//队列
                .to(deadExchange)//要绑定的交换机
                .with("spu.dead");//路由key

    }


    /**
     * 创建业务队列(绑定死信交换机+死信消息的路由key) + 业务交换机 + 绑定
     * 业务队列的消息消费时可能有临时异常，可以将暂时不能正确消费的消息丢弃到死信队列中储存
     */
    //业务交换机
    @Bean
    public TopicExchange serviceExchange() {
        return ExchangeBuilder.topicExchange(GmallConsts.SAVE_SPU_EXCHANGE_NAME)
                .durable(true)
                .ignoreDeclarationExceptions()
                .build();
    }

    //业务队列
    @Bean
    public Queue serviceQueue() {
        return QueueBuilder.durable(GmallConsts.SAVE_SPU_QUEUE_NAME)
                .deadLetterExchange("spu_dead_exchange")//配置死信交换机的名称
                .deadLetterRoutingKey("spu.dead") //配置死信队列的路由key,这样消息丢弃时，就会丢弃到死信队列
                .build();
    }

    //将上面的业务队列和业务交换机用路由key绑定起来
    @Bean
    public Binding serviceBind(TopicExchange serviceExchange, Queue serviceQueue) {
        return BindingBuilder.bind(serviceQueue)
                .to(serviceExchange)
                .with(GmallConsts.SAVE_SPU_ROUTING_KEY);
    }

}
